#include "stdafx.h"
#include "GlobalDBDef.h"
#include "ServiceManager_OverlapJob.h"
#include "ServiceManager_MsgDef.h"

#include "../../NSNetLibSrc/Framework/Serverframework/ServerFramework_Database.h"
#include "../../NSNetLibSrc/Framework/ServerFramework/ServerProcessBase.h"
#include "../../NSNetLibSrc/Framework/ServerFramework/ServerFramework_Security.h"
#include "../../NSNetLibSrc/Include/NetFramework_MsgDef.h"

#include "GlobalManager.h"
#include "ServiceManagerProcess.h"

#include "../../NSNetLibSrc/Library/bslib/db/db_common.h"

#include "SMC_LOG_TYPE.h"

Database g_database;

IMPLEMENT_OVERLAPJOB_ALLOCATOR(COverlapJob_SM_ModuleVersion, CChunkAllocatorST);
IMPLEMENT_OVERLAPJOB_ALLOCATOR(COverlapJob_SM_ModuleVersionFile, CChunkAllocatorST);
IMPLEMENT_ITEMPOOL_ALLOCATOR(sSMDefault_RelayMsg_Param, CChunkAllocatorST);

//------------------------------------------------------------------------------
void COverlapJob_SM_ModuleVersion::Init(CTask* pOwnerTask, DWORD dwSessionID)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID = dwSessionID;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersion::Prepare()
{
	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersion::DoWork()
{
	sQueryStatement statement;
	::ZeroMemory( &statement, sizeof(statement) );
	statement.m_pTrigger = nullptr;
	statement.m_RowSize = sizeof(sModuleVersion);
	statement.m_BufferSize = sizeof(sModuleVersion);

	SQLQueryModuleVersion query;
	statement.m_pQuery = &query;
	query.SetModuleID( 0 );	//all

	if( ExecQuery(g_database, statement) == false )
	{
		return false;
	}

	CMsg* pAck = NEWMSG(FALSE);
	pAck->SetMsgID( SMMSG_MODULEVERSION_ACK);

	*pAck << (BYTE)RESULT_SUCCESS;
	const SQLQueryModuleVersion::VECTOR_RECORDSETS& records = query.recordsets();
	for each( const sModuleVersion& data in records )
	{
		*pAck << (BYTE)1;
		*pAck << data.m_nID << data.m_nModuleID;
		*pAck << data.m_nVersion << data.m_szVersion << data.m_szDesc;
		*pAck << data.m_nValid;
	}

	*pAck << (BYTE)0;

	g_pNetEngine->SendMsg(m_dwSessionID, pAck);
	DELMSG(pAck);
	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersion::Commit()
{
	//nothing to do..
	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersion::Rollback()
{
	CMsg* pAck = NEWMSG(FALSE);
	pAck->SetMsgID( SMMSG_MODULEVERSION_ACK);
	*pAck << RESULT_FAIL;	
	g_pNetEngine->SendMsg(m_dwSessionID, pAck);
	DELMSG(pAck);
	return true;
}

/*************************************************************************************************************
..............................................................................................................
......................SSSS...EEEEEE..PPPPP.....AA....RRRRR.....AA....TTTTTT...OOOO...RRRRR....................
.....................SS..SS..EE......PP..PP...AAAA...RR..RR...AAAA.....TT....OO..OO..RR..RR...................
.....................SS......EE......PP..PP..AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PPPPP...AAAAAA..RRRR....AAAAAA....TT....OO..OO..RRRR.....................
.........................SS..EE......PP......AA..AA..RR.RR...AA..AA....TT....OO..OO..RR.RR....................
.....................SS..SS..EE......PP......AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PP......AA..AA..RR..RR..AA..AA....TT.....OOOO...RR..RR...................
..............................................................................................................
*************************************************************************************************************/
void COverlapJob_SM_ModuleVersionFile::Init(CTask* pOwnerTask, DWORD dwSessionID,BYTE nModuleID,BYTE nContentID)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID = dwSessionID;

	m_nModuleID = nModuleID;
	m_nContentID = nContentID;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersionFile::Prepare()
{
	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersionFile::DoWork()
{	
	CMsg* pAck = NEWMSG( FALSE );
	pAck->SetMsgID(SMMSG_MODULEVERSIONFILE_ACK);
	*pAck << (BYTE)RESULT_SUCCESS;

	sQueryStatement statement;
	::ZeroMemory( &statement, sizeof( sQueryStatement));

	statement.m_pTrigger = nullptr;
	statement.m_RowSize = sizeof(sModuleVersionFile);
	statement.m_BufferSize = sizeof(sModuleVersionFile);

	SQLQueryModuleVersionFile query;
	statement.m_pQuery = &query;
	query.SetModuleID( m_nModuleID );
	query.SetContentID( m_nContentID );
	
	if( ExecQuery(g_database, statement) == false )
		return false;

	const SQLQueryModuleVersionFile::VECTOR_RECORDSETS& records = query.recordsets();
	for each( const sModuleVersionFile& data in records )
	{
		*pAck << (BYTE)1 << data;
	}

	*pAck << (BYTE)0;
	g_pNetEngine->SendMsg(m_dwSessionID, pAck);
	DELMSG(pAck);
	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersionFile::Commit()
{
	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_SM_ModuleVersionFile::Rollback()
{
	CMsg* pAck = NEWMSG(FALSE);
	pAck->SetMsgID( SMMSG_MODULEVERSIONFILE_ACK);
	*pAck << (BYTE)RESULT_FAIL;
	g_pNetEngine->SendMsg(m_dwSessionID, pAck);
	DELMSG(pAck);
	return true;
}

/*************************************************************************************************************
..............................................................................................................
......................SSSS...EEEEEE..PPPPP.....AA....RRRRR.....AA....TTTTTT...OOOO...RRRRR....................
.....................SS..SS..EE......PP..PP...AAAA...RR..RR...AAAA.....TT....OO..OO..RR..RR...................
.....................SS......EE......PP..PP..AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PPPPP...AAAAAA..RRRR....AAAAAA....TT....OO..OO..RRRR.....................
.........................SS..EE......PP......AA..AA..RR.RR...AA..AA....TT....OO..OO..RR.RR....................
.....................SS..SS..EE......PP......AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PP......AA..AA..RR..RR..AA..AA....TT.....OOOO...RR..RR...................
..............................................................................................................
*************************************************************************************************************/
IMPLEMENT_OVERLAPJOB_ALLOCATOR(COverlapJob_RecordPatchData, CChunkAllocatorST);

//------------------------------------------------------------------------------
void COverlapJob_RecordPatchData::Init(CTask* pOwnerTask,sModuleVersion* pModuleVersion,LIST_ModuleVersionFile* pFileList,DWORD dwPatchUserSessionID)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_pModuleVersion = pModuleVersion;
	m_pFileList = pFileList;

	m_dwPatchUserSessionID = dwPatchUserSessionID;
}

//------------------------------------------------------------------------------
bool COverlapJob_RecordPatchData::Prepare()
{
	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_RecordPatchData::DoWork()
{
	sQueryStatement statement;
	::ZeroMemory( &statement, sizeof(sQueryStatement));
	
	size_t TotalCount = m_pFileList->size();
	int nExecCount = 0;
	BYTE btProgress = 0;

	USES_CONVERSION;
	for each( sModuleVersionFile* pFile in *m_pFileList )
	{
		if( g_pNetEngine->GetSessionType( m_dwPatchUserSessionID) == SESSION_TYPE_INVALID)
		{
			m_dwPatchUserSessionID = 0;
			return false;
		}

		WCHAR szPathTemp[ MAX_PATH];
		if( ::wcslen( pFile->m_szPath) == 0)
		{
			SF_strcpy( szPathTemp, MAX_PATH, L".");
			}
		else
		{
			SF_strcpy( szPathTemp, MAX_PATH, pFile->m_szPath);
			}

		SQLQueryUpdateModuleVersionFile query;
		query.Setmodule_id( pFile->m_nModuleID );
		query.Setversion( pFile->m_nVersion );
		query.Setfilename( W2A(pFile->m_szFilename) );
		query.Setpath( W2A(pFile->m_szPath) );
		query.Setsize( pFile->m_nFileSize );
		query.Setfile_date( pFile->m_timeModified );
	
		statement.m_pQuery = &query;
		if( ExecQuery(g_database, statement) == false )
		{
			return false;
		}

		nExecCount ++;

		if( abs( (nExecCount * 100 / (int)TotalCount) - btProgress) > 1)
		{
			CMsg* pAckMsg = NEWMSG( FALSE);
			pAckMsg->SetMsgID( SMMSG_PATCH_NOTIFY);
			*pAckMsg << PATCH_NOTIFY_MASK_RECORDING_DB << PATCH_NOTIFY_RECORDING_DB_PROGRESS << btProgress;
			g_pNetEngine->SendMsg( m_dwPatchUserSessionID, pAckMsg);
			DELMSG( pAckMsg);

			btProgress = (BYTE)(nExecCount * 100 / (int)TotalCount);
		}
	}

	if( g_pNetEngine->GetSessionType( m_dwPatchUserSessionID) == SESSION_TYPE_INVALID)
	{
		m_dwPatchUserSessionID = 0;
		return false;
	}

	::ZeroMemory( &statement, sizeof(sQueryStatement));

	SQLQueryUpdateModuleVersion query;
	query.Setmodule_id( m_pModuleVersion->m_nModuleID );
	query.Setversion( m_pModuleVersion->m_nVersion );
	query.SetstrVersion( W2A(m_pModuleVersion->m_szVersion) );
	query.SetstrVerDesc( W2A(m_pModuleVersion->m_szDesc) );

	statement.m_pQuery = &query;

	bool query_result = ExecQuery( g_database, statement );
	return query_result;
}

//------------------------------------------------------------------------------
bool COverlapJob_RecordPatchData::Commit()
{
	ReleaseModuleVersionData();
	
	if( m_dwPatchUserSessionID > 0)
	{
		CMsg* pAckMsg = NEWMSG( FALSE);
		pAckMsg->SetMsgID( SMMSG_PATCH_END_UPLOAD);
		*pAckMsg << RESULT_SUCCESS;

		g_pNetEngine->SendMsg( m_dwPatchUserSessionID, pAckMsg);
		DELMSG( pAckMsg);
	}

	return true;
}

//------------------------------------------------------------------------------
bool COverlapJob_RecordPatchData::Rollback()
{
	ReleaseModuleVersionData();

	if( m_dwPatchUserSessionID > 0)
	{
		CMsg* pAckMsg = NEWMSG( FALSE);
		pAckMsg->SetMsgID( SMMSG_PATCH_END_UPLOAD);
		*pAckMsg << RESULT_FAIL << PATCH_UPLOAD_FAIL_RECORDING_DB;

		g_pNetEngine->SendMsg( m_dwPatchUserSessionID, pAckMsg);
		DELMSG( pAckMsg);
	}

	return true;
}

//------------------------------------------------------------------------------
IMPLEMENT_OVERLAPJOB_ALLOCATOR( COverlapJob_RefreshSecurityData_n_SendToSM, CChunkAllocatorST)

void COverlapJob_RefreshSecurityData_n_SendToSM::Init(CTask* pOwnerTask,DWORD dwSessionID)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID = dwSessionID;
}

bool COverlapJob_RefreshSecurityData_n_SendToSM::Prepare()
{
	return true;
}

bool COverlapJob_RefreshSecurityData_n_SendToSM::DoWork()
{
	LIST_SecurityDescription*				pList_SecurityDescription = new LIST_SecurityDescription;
	LIST_SecurityDescriptionGroup*			pList_SecurityDescriptionGroup = new LIST_SecurityDescriptionGroup;
	LIST_SecurityDescriptionGroupAssign*	pList_SecurityDescriptionGroupAssign = new LIST_SecurityDescriptionGroupAssign;

	CClassTrigger<COverlapJob_RefreshSecurityData_n_SendToSM> trigger( this, &COverlapJob_RefreshSecurityData_n_SendToSM::QueryTrigger_SecurityData);

	sQueryStatement statement;
	statement.m_pTrigger = &trigger;
	statement.m_Param[ 0] = 0;
	statement.m_Param[ 1] = (ULONG_PTR)pList_SecurityDescription;
	if (SF_strcpy( statement.m_szQuery, MAX_QUERY_LEN, L"select * from _SecurityDescription with (NOLOCK)") != S_OK)
	{
		_ASSERT(FALSE);
		return false;
	}

	/*
	if( ExecQuery( &statement) < 0)
		return false;

	statement.m_Param[ 0] = 1;
	statement.m_Param[ 1] = (ULONG_PTR)pList_SecurityDescriptionGroup;
	if (SF_strcpy( statement.m_szQuery, MAX_QUERY_LEN, L"select * from _SecurityDescriptionGroup with (NOLOCK)") != S_OK)
	{
		_ASSERT(FALSE);
		return false;
	}

	if( ExecQuery( &statement) < 0)
		return false;

	statement.m_Param[ 0] = 2;
	statement.m_Param[ 1] = (ULONG_PTR)pList_SecurityDescriptionGroupAssign;
	if (SF_strcpy( statement.m_szQuery, MAX_QUERY_LEN, L"select * from _SecurityDescriptionGroupAssign with (NOLOCK)") != S_OK)
	{
		_ASSERT(FALSE);
		return false;
	}

	if( ExecQuery( &statement) < 0)
		return false;

	ReleaseSecurityDescription();
	BuildSecurityDescription( pList_SecurityDescriptionGroup, pList_SecurityDescription, pList_SecurityDescriptionGroupAssign);
	*/
	return true;
}

bool COverlapJob_RefreshSecurityData_n_SendToSM::Commit()
{
	CMsg* pMassiveMsg = NEWMSG(FALSE);
	pMassiveMsg->SetMsgID( SMMSG_REFRESH_SECURITY_DATA);
	*pMassiveMsg << RESULT_SUCCESS;
	PushSecurityDescription( pMassiveMsg);
	g_pNetEngine->SendMsg(m_dwSessionID, pMassiveMsg);
	DELMSG(pMassiveMsg);
	return true;
}

bool COverlapJob_RefreshSecurityData_n_SendToSM::Rollback()
{
	CMsg* pMassiveMsg = NEWMSG(FALSE);
	pMassiveMsg->SetMsgID( SMMSG_REFRESH_SECURITY_DATA);
	*pMassiveMsg << RESULT_FAIL;
	g_pNetEngine->SendMsg(m_dwSessionID, pMassiveMsg);
	DELMSG(pMassiveMsg);
	return true;
}

int COverlapJob_RefreshSecurityData_n_SendToSM::QueryTrigger_SecurityData(ULONG_PTR ptrContext)
{
	sQueryStatement* pStatement = (sQueryStatement*)ptrContext;

	if( pStatement->m_nState == 0)
	{
		switch( pStatement->m_Param[ 0])
		{
		case 0:
			pStatement->m_pBuffer = (void**)new sSecurityDescription;
			pStatement->m_RowSize = sizeof( sSecurityDescription);
			break;
		case 1:
			pStatement->m_pBuffer = (void**)new sSecurityDescriptionGroup;
			pStatement->m_RowSize = sizeof( sSecurityDescriptionGroup);
			break;
		case 2:
			pStatement->m_pBuffer = (void**)new sSecurityDescriptionGroupAssign;
			pStatement->m_RowSize = sizeof( sSecurityDescriptionGroupAssign);
			break;
		}

		ZeroMemory( pStatement->m_pBuffer, pStatement->m_RowSize);
	}
	else
	{
		switch( pStatement->m_Param[ 0])
		{
		case 0:
			((LIST_SecurityDescription*)pStatement->m_Param[ 1])->push_back( (sSecurityDescription*)pStatement->m_pBuffer);
			break;
		case 1:
			((LIST_SecurityDescriptionGroup*)pStatement->m_Param[ 1])->push_back( (sSecurityDescriptionGroup*)pStatement->m_pBuffer);
			break;
		case 2:
			((LIST_SecurityDescriptionGroupAssign*)pStatement->m_Param[ 1])->push_back( (sSecurityDescriptionGroupAssign*)pStatement->m_pBuffer);
			break;
		}
	}
	return TRUE;
}

//------------------------------------------------------------------------------
IMPLEMENT_OVERLAPJOB_ALLOCATOR( COverlapJob_QueryUser, CChunkAllocatorST);

void COverlapJob_QueryUser::Init(CTask* pOwnerTask,DWORD dwSessionID,LPCTSTR szQuery)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID = dwSessionID;
	m_szQuery = szQuery;

	m_pMassiveMsg = NEWMSG(FALSE);
	m_pMassiveMsg->SetMsgID( SMMSG_QUERY_USER_ACK);
	*m_pMassiveMsg << RESULT_SUCCESS;
}

bool COverlapJob_QueryUser::Prepare()
{
	return true;
}

bool COverlapJob_QueryUser::DoWork()
{
	_User user;

	CClassTrigger<COverlapJob_QueryUser> trigger( this, &COverlapJob_QueryUser::QueryTrigger_QueryUser);

	sQueryStatement statement;
	statement.m_pTrigger = &trigger;
	statement.m_Param[ 0] = (ULONG_PTR)&user;
	statement.m_Param[ 1] = (ULONG_PTR)m_pMassiveMsg;

	/*
	if( ExecQueryF( &statement, L"exec _QueryUser '%s'", m_szQuery.c_str()) < 0)
	{
		DELMSG(m_pMassiveMsg);
		m_pMassiveMsg = NULL;
		return false;
	}
	*/

	return true;
}

bool COverlapJob_QueryUser::Commit()
{
	*m_pMassiveMsg << (BYTE)0;
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

bool COverlapJob_QueryUser::Rollback()
{
	CMsg* pMassiveMsg = NEWMSG(FALSE);
	pMassiveMsg->SetMsgID( SMMSG_QUERY_USER_ACK);
	*pMassiveMsg << RESULT_FAIL << SMMSG_QUERY_USER_FAIL_DB_ERROR;
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

int COverlapJob_QueryUser::QueryTrigger_QueryUser(ULONG_PTR ptrContext)
{
	sQueryStatement* pStatement = (sQueryStatement*)ptrContext;

	if( pStatement->m_nState == 0)
	{
		pStatement->m_pBuffer = (void*)pStatement->m_Param[ 0];
		pStatement->m_RowSize = sizeof( _User);
		pStatement->m_BufferSize = sizeof( _User);

		ZeroMemory( pStatement->m_pBuffer, sizeof( _User));
	}
	else
	{
		CMsg* pMassiveMsg = (CMsg*)pStatement->m_Param[ 1];
		*pMassiveMsg << (BYTE)0x1 << *(_User*)pStatement->m_pBuffer;
	}

	return TRUE;
}

//------------------------------------------------------------------------------
IMPLEMENT_OVERLAPJOB_ALLOCATOR(COverlapJob_SMLog, CChunkAllocatorST);

void COverlapJob_SMLog::Init(CTask* pOwnerTask, std::wstring& szUserID, BYTE btCatagory, LPCWSTR szLog)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_strUserID = szUserID;
	m_btCatagory = btCatagory;
	m_szLog = szLog;
}

bool COverlapJob_SMLog::Prepare()
{
	return true;
}

bool COverlapJob_SMLog::DoWork()
{
	sQueryStatement statement;
	ZeroMemory( &statement, sizeof( sQueryStatement));

	/*
	ExecQueryF( &statement, L"insert _SMCLog values ('%s', %d, '%s', default)", 
		m_strUserID.c_str(), m_btCatagory, m_szLog.c_str());
*/

	return true;
}

bool COverlapJob_SMLog::Commit()
{
	return true;
}

bool COverlapJob_SMLog::Rollback()
{
	return true;
}

//------------------------------------------------------------------------------
IMPLEMENT_OVERLAPJOB_ALLOCATOR(COverlapJob_QuerySMLog, CChunkAllocatorST);

void COverlapJob_QuerySMLog::Init(CTask* pOwnerTask,DWORD dwSessionID,std::wstring& szUserID,BYTE btCatagory, LPCTSTR szTimeBegin,LPCTSTR szTimeEnd)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID = dwSessionID;
	m_szUserID = szUserID;
	m_btCatagory = btCatagory;
	m_szTimeBegin = szTimeBegin;
	m_szTimeEnd = szTimeEnd;

	m_pMassiveMsg = NEWMSG(FALSE);
	m_pMassiveMsg->SetMsgID( SMMSG_QUERY_SMLOG_ACK);
	*m_pMassiveMsg << RESULT_SUCCESS;
}

bool COverlapJob_QuerySMLog::Prepare()
{
	return true;
}

bool COverlapJob_QuerySMLog::DoWork()
{
	CClassTrigger<COverlapJob_QuerySMLog> trigger( this, &COverlapJob_QuerySMLog::QueryTrigger_QuerySMLog);

	_SMLog log;

	sQueryStatement statement;
	statement.m_pTrigger	= &trigger;
	statement.m_Param[ 0]	= (ULONG_PTR)&log;
	statement.m_Param[ 1]	= (ULONG_PTR)m_pMassiveMsg;

	/*
	if( ExecQueryF( &statement, L"exec _GetSMLog %d, '%s', '%s', '%s'", m_btCatagory, m_szUserID.c_str(), m_szTimeBegin.c_str(), m_szTimeEnd.c_str()) < 0)
	{
		goto error;
	}

	return true;
	
error:
	DELMSG(m_pMassiveMsg);
	m_pMassiveMsg = NULL;
	*/
	return false;
}

bool COverlapJob_QuerySMLog::Commit()
{
	*m_pMassiveMsg << (BYTE)0;
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

bool COverlapJob_QuerySMLog::Rollback()
{
	CMsg* pMassiveMsg = NEWMSG(FALSE);
	pMassiveMsg->SetMsgID( SMMSG_QUERY_SMLOG_ACK);
	*pMassiveMsg << RESULT_FAIL;
	g_pNetEngine->SendMsg(m_dwSessionID, pMassiveMsg);
	DELMSG(pMassiveMsg);
	return true;
}

int COverlapJob_QuerySMLog::QueryTrigger_QuerySMLog(ULONG_PTR ptrContext)
{
	sQueryStatement* pStatement = (sQueryStatement*)ptrContext;

	if( pStatement->m_nState == 0)
	{
		pStatement->m_pBuffer = (void*)pStatement->m_Param[ 0];
		pStatement->m_RowSize = sizeof( _SMLog);
		pStatement->m_BufferSize = sizeof( _SMLog);

		ZeroMemory( pStatement->m_pBuffer, sizeof( _SMLog));
	}
	else
	{
		CMsg* pMassiveMsg = (CMsg*)pStatement->m_Param[ 1];
		*pMassiveMsg << (BYTE)0x1 << *(_SMLog*)pStatement->m_pBuffer;
	}

	return TRUE;
}

/*************************************************************************************************************
..............................................................................................................
......................SSSS...EEEEEE..PPPPP.....AA....RRRRR.....AA....TTTTTT...OOOO...RRRRR....................
.....................SS..SS..EE......PP..PP...AAAA...RR..RR...AAAA.....TT....OO..OO..RR..RR...................
.....................SS......EE......PP..PP..AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PPPPP...AAAAAA..RRRR....AAAAAA....TT....OO..OO..RRRR.....................
.........................SS..EE......PP......AA..AA..RR.RR...AA..AA....TT....OO..OO..RR.RR....................
.....................SS..SS..EE......PP......AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PP......AA..AA..RR..RR..AA..AA....TT.....OOOO...RR..RR...................
..............................................................................................................
*************************************************************************************************************/
IMPLEMENT_OVERLAPJOB_ALLOCATOR(COverlapJob_QueryContentUserAccount, CChunkAllocatorST);

void COverlapJob_QueryContentUserAccount::Init(CTask* pOwnerTask,DWORD dwSessionID,BYTE btCondition, LPCTSTR szQueryString)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID = dwSessionID;
	m_szQueryString = szQueryString;
	m_btCondition = btCondition;

	m_pMassiveMsg = NEWMSG(FALSE);
	m_pMassiveMsg->SetMsgID( SMMSG_QUERY_CONTENT_USER_ACCOUNT_ACK);
	*m_pMassiveMsg << RESULT_SUCCESS;
}

bool COverlapJob_QueryContentUserAccount::Prepare()
{
	return true;
}

bool COverlapJob_QueryContentUserAccount::DoWork()
{
	CClassTrigger<COverlapJob_QueryContentUserAccount> trigger( this, &COverlapJob_QueryContentUserAccount::QueryTrigger_QueryContentUserAccount);

	_ContentUserCurInfo user_info;

	sQueryStatement statement;
	statement.m_pTrigger = &trigger;
	statement.m_Param[ 0] = (ULONG_PTR)&user_info;
	statement.m_Param[ 1] = (ULONG_PTR)m_pMassiveMsg;

	/*
	if( ExecQueryF( &statement
					, L"exec _ViewContentUser %d,'%s'"
					, m_btCondition
					, m_szQueryString.c_str()) < 0)
	{
		goto error;
	}

	return true;
error:
	DELMSG(m_pMassiveMsg);
	m_pMassiveMsg = NULL;
	*/
	return false;
}

bool COverlapJob_QueryContentUserAccount::Commit()
{
	*m_pMassiveMsg << (BYTE)0;
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

bool COverlapJob_QueryContentUserAccount::Rollback()
{
	CMsg* pMassiveMsg = NEWMSG(FALSE);
	pMassiveMsg->SetMsgID( SMMSG_QUERY_CONTENT_USER_ACCOUNT_ACK);
	*pMassiveMsg << RESULT_FAIL;
	g_pNetEngine->SendMsg(m_dwSessionID, pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

int COverlapJob_QueryContentUserAccount::QueryTrigger_QueryContentUserAccount(ULONG_PTR ptrContext)
{
	sQueryStatement* pStatement = (sQueryStatement*)ptrContext;

	if( pStatement->m_nState == 0)
	{
		pStatement->m_pBuffer = (void*)pStatement->m_Param[ 0];
		pStatement->m_RowSize = sizeof( _ContentUserCurInfo);
		pStatement->m_BufferSize = sizeof( _ContentUserCurInfo);

		ZeroMemory( pStatement->m_pBuffer, sizeof( _ContentUserCurInfo));
	}
	else
	{
		CMsg* pMassiveMsg = (CMsg*)pStatement->m_Param[ 1];
		*pMassiveMsg << (BYTE)0x1 << *(_ContentUserCurInfo*)pStatement->m_pBuffer;
	}
	
	return TRUE;
}

/*************************************************************************************************************
..............................................................................................................
......................SSSS...EEEEEE..PPPPP.....AA....RRRRR.....AA....TTTTTT...OOOO...RRRRR....................
.....................SS..SS..EE......PP..PP...AAAA...RR..RR...AAAA.....TT....OO..OO..RR..RR...................
.....................SS......EE......PP..PP..AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PPPPP...AAAAAA..RRRR....AAAAAA....TT....OO..OO..RRRR.....................
.........................SS..EE......PP......AA..AA..RR.RR...AA..AA....TT....OO..OO..RR.RR....................
.....................SS..SS..EE......PP......AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PP......AA..AA..RR..RR..AA..AA....TT.....OOOO...RR..RR...................
..............................................................................................................
*************************************************************************************************************/
IMPLEMENT_OVERLAPJOB_ALLOCATOR(COverlapJob_PreparePatch, CChunkAllocatorST);

void COverlapJob_PreparePatch::Init(CTask* pOwnerTask,DWORD dwSessionID,DWORD ModuleID)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID = dwSessionID;
	m_ModuleID = ModuleID;
}

bool COverlapJob_PreparePatch::Prepare()
{
	if( g_pNetEngine->GetSessionType( m_dwSessionID) == SESSION_TYPE_INVALID)
		return false;

	return true;
}

bool COverlapJob_PreparePatch::DoWork()
{
	SQLQueryModuleVersion queryVersion;
	SQLQueryModuleVersionFile queryVersionFile;

	sQueryStatement statement;
	::ZeroMemory( &statement, sizeof(statement) );
	statement.m_RowSize = sizeof(sModuleVersion);
	statement.m_BufferSize = sizeof(sModuleVersion);
	{
		statement.m_pQuery = &queryVersion;
		queryVersion.SetModuleID( m_ModuleID );

		if( ExecQuery(g_database, statement) == false )
		{
			ReportLog(LOG_FATAL, _T("an error occured during select SQLQueryModuleVersion data from DB [ModuleID: %d]"), m_ModuleID);
			return false;
		}
	}

	::ZeroMemory( &statement, sizeof(statement) );
	statement.m_RowSize = sizeof(sModuleVersionFile);
	statement.m_BufferSize = sizeof(sModuleVersionFile);
	{
		statement.m_pQuery = &queryVersion;
		queryVersionFile.SetModuleID( m_ModuleID );

		if( ExecQuery(g_database, statement) == false )
		{
			ReportLog(LOG_FATAL, _T("an error occured during select SQLQueryModuleVersionFile data from DB [ModuleID: %d]"), m_ModuleID);
			return false;
		}
	}

	const SQLQueryModuleVersion::VECTOR_RECORDSETS& version_records = queryVersion.recordsets();
	const SQLQueryModuleVersionFile::VECTOR_RECORDSETS& version_file_records = queryVersionFile.recordsets();
	if( version_records.empty() == true )
	{
		//ReportLog(LOG_FATAL, _T("can't find any version info from table _ModuleVersion [ModuleID: %d]"), m_ModuleID);
		return false;
	}

	m_pMassiveMsg = NEWMSG(FALSE);
	m_pMassiveMsg->SetMsgID( SMMSG_PREPARE_PATCH_ACK);
	*m_pMassiveMsg << RESULT_SUCCESS;

	for each( const sModuleVersion& data in version_records )
	{
		*m_pMassiveMsg << (BYTE)1;
		*m_pMassiveMsg << data.m_nID << data.m_nModuleID;
		*m_pMassiveMsg << data.m_nVersion << data.m_szVersion << data.m_szDesc << data.m_nValid;
	}
	*m_pMassiveMsg << (BYTE)0;
	
	for each( const sModuleVersionFile& data in version_file_records )
	{
		*m_pMassiveMsg << (BYTE)1;
		*m_pMassiveMsg << data.m_nID << data.m_nVersion << data.m_nModuleID;
		*m_pMassiveMsg << data.m_szFilename << data.m_szPath;
		*m_pMassiveMsg << data.m_nFileSize << data.m_timeModified << data.m_nValid;
	}
	*m_pMassiveMsg << (BYTE)0;
	return true;
}

bool COverlapJob_PreparePatch::Commit()
{
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

bool COverlapJob_PreparePatch::Rollback()
{
	m_pMassiveMsg = NEWMSG(FALSE);
	m_pMassiveMsg->SetMsgID( SMMSG_PREPARE_PATCH_ACK);
	*m_pMassiveMsg << RESULT_FAIL << PREPARE_PATCH_FAIL_DB_ERROR;
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}


/*************************************************************************************************************
..............................................................................................................
......................SSSS...EEEEEE..PPPPP.....AA....RRRRR.....AA....TTTTTT...OOOO...RRRRR....................
.....................SS..SS..EE......PP..PP...AAAA...RR..RR...AAAA.....TT....OO..OO..RR..RR...................
.....................SS......EE......PP..PP..AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PPPPP...AAAAAA..RRRR....AAAAAA....TT....OO..OO..RRRR.....................
.........................SS..EE......PP......AA..AA..RR.RR...AA..AA....TT....OO..OO..RR.RR....................
.....................SS..SS..EE......PP......AA..AA..RR..RR..AA..AA....TT....OO..OO..RR..RR...................
......................SSSS...EEEEEE..PP......AA..AA..RR..RR..AA..AA....TT.....OOOO...RR..RR...................
..............................................................................................................
*************************************************************************************************************/
IMPLEMENT_OVERLAPJOB_ALLOCATOR( COverlapJob_ConcurrentUserLogJob,CChunkAllocatorST);

void COverlapJob_ConcurrentUserLogJob::Init(CTask* pOwnerTask,DWORD dwSessionID, DWORD nShardID, BYTE btPeriod, 
											std::wstring& szBeginDateTime, std::wstring& szEndDateTime)
{
	COverlapJob_Local::Init( pOwnerTask);

	m_dwSessionID		= dwSessionID;
	
	m_nShardID			= nShardID;
	m_btPeriod			= btPeriod;
	m_szBeginDateTime	= szBeginDateTime;
	m_szEndDateTime		= szEndDateTime;

	m_pMassiveMsg = NEWMSG(FALSE);
}

bool COverlapJob_ConcurrentUserLogJob::Prepare()
{
	return true;
}

bool COverlapJob_ConcurrentUserLogJob::DoWork()
{
	m_pMassiveMsg->SetMsgID( SMMSG_QUERY_CONCURRENT_USER_LOG_ACK);

	*m_pMassiveMsg << m_nShardID;

	_ConcurrentUserLog	LogData;
	sQueryStatement		statement;
	ZeroMemory( &statement, sizeof( sQueryStatement));

	CClassTrigger<COverlapJob_ConcurrentUserLogJob> trigger( this, &COverlapJob_ConcurrentUserLogJob::QueryTrigger_ConcurrentUserLog);
	statement.m_pBuffer		= &LogData;
	statement.m_RowSize		= sizeof( _ConcurrentUserLog);
	statement.m_BufferSize	= sizeof( _ConcurrentUserLog);
	statement.m_pTrigger	= &trigger;

	/*
	if( ExecQueryF( &statement, L"exec _GetConcurrentUserLog %d, %d, '%s', '%s' ", 
		m_nShardID, m_btPeriod, m_szBeginDateTime.c_str(), m_szEndDateTime.c_str()) < 0)
	{
		return false;
	}
	*/
	*m_pMassiveMsg << (BYTE)0x00;

	return true;
}

bool COverlapJob_ConcurrentUserLogJob::Commit()
{
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

bool COverlapJob_ConcurrentUserLogJob::Rollback()
{
	*m_pMassiveMsg << (BYTE)0x00;
	g_pNetEngine->SendMsg(m_dwSessionID, m_pMassiveMsg);
	DELMSG(m_pMassiveMsg);
	return true;
}

int COverlapJob_ConcurrentUserLogJob::QueryTrigger_ConcurrentUserLog(ULONG_PTR ptrContext)
{
	sQueryStatement* pStatement = (sQueryStatement*)ptrContext;

	if( pStatement->m_nState == 0)
	{
		ZeroMemory( pStatement->m_pBuffer, sizeof( _ConcurrentUserLog));
	}
	else
	{
		*m_pMassiveMsg << (BYTE)0x01 << *(_ConcurrentUserLog*)pStatement->m_pBuffer;
	}
	return TRUE;
}
